import java.time.LocalDate;
import java.time.Month;
import java.util.*;

//添加功能
class Income {
    private LocalDate date;
    private double amount;
    private String category;
    private String note;
    public Income(LocalDate date, double amount, String category, String note) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }
    // Getters and toString() method
    public LocalDate getDate() { return date; }
    public double getAmount() { return amount; }
    public String getCategory() { return category; }
    public String getNote() { return note; }
    @Override
    public String toString() {
        return "Income{" +
                "date=" + date +
                ", amount=" + amount +
                ", category='" + category + '\'' +
                ", note='" + note + '\'' +
                '}';
    }
}
class Expense {
    private LocalDate date;
    private double amount;
    private String category;
    private String note;
    public Expense(LocalDate date, double amount, String category, String note) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }
    // Getters and toString() method
    public LocalDate getDate() { return date; }
    public double getAmount() { return amount; }
    public String getCategory() { return category; }
    public String getNote() { return note; }
    @Override
    public String toString() {
        return "Expense{" +
                "date=" + date +
                ", amount=" + amount +
                ", category='" + category + '\'' +
                ", note='" + note + '\'' +
                '}';
    }
}
public class Bill {
    private List<Income> incomes = new ArrayList<>();
    private List<Expense> expenses = new ArrayList<>();
    private double monthlyBudget;
    // 使用 Map<Month, Map<String, Double>> 来存储每个月的按类别统计数据
    private Map<Month, Map<String, Double>> monthlyIncomeByCategory = new HashMap<>();
    private Map<Month, Map<String, Double>> monthlyExpenseByCategory = new HashMap<>();
    // 使用 Map<Month, Double> 来存储每个月的总收入和总支出
    private Map<Month, Double> monthlyTotalIncome = new HashMap<>();
    private Map<Month, Double> monthlyTotalExpense = new HashMap<>();
    public Bill() {
        this.monthlyBudget = 0; // Default budget is 0, user should set it
        for (Month month : Month.values()) {
            monthlyIncomeByCategory.put(month, new HashMap<>());
            monthlyExpenseByCategory.put(month, new HashMap<>());
            monthlyTotalIncome.put(month, 0.0);
            monthlyTotalExpense.put(month, 0.0);
        }
    }
    public static void main(String[] args) {
        Bill bill = new Bill();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("欢迎使用个人账单管理系统");
            System.out.println("1. 记录收入");
            System.out.println("2. 记录支出");
            System.out.println("3. 查看所有账单");
            System.out.println("4. 查询账单");
            System.out.println("5. 设置月度预算");
            System.out.println("6. 查看月度统计");
            System.out.println("7. 退出系统");
            System.out.print("请输入选项序号: ");
            int choice = scanner.nextInt();
            scanner.nextLine();
            switch (choice) {
                case 1:
                    bill.recordIncome(scanner);
                    break;
                case 2:
                    bill.recordExpense(scanner);
                    break;
                case 3:
                    bill.displayBills();
                    break;
                case 4:
                    bill.queryBills(scanner);
                    break;
                case 5:
                    bill.setMonthlyBudget(scanner);
                    break;
                case 6:
                    bill.showMonthlyStatistics();
                    break;
                case 7:
                    System.out.println("退出系统");
                    return;
                default:
                    System.out.println("无效的选项，请重新输入。");
            }
        }
    }
    private void recordIncome(Scanner scanner) {
        System.out.println("请输入收入信息：");
        System.out.print("日期 (yyyy-MM-dd): ");
        String dateStr = scanner.nextLine();
        LocalDate date = LocalDate.parse(dateStr);
        double amount;
        while (true) {
            System.out.print("金额: ");
            amount = scanner.nextDouble();
            scanner.nextLine();
            if (amount > 0) {
                break;
            } else {
                System.out.println("金额必须为正数，请重新输入。");
            }
        }
        System.out.print("类别 (如工资、奖金等): ");
        String category = scanner.nextLine();
        System.out.print("备注: ");
        String note = scanner.nextLine();
        Income income = new Income(date, amount, category, note);
        incomes.add(income);
        updateMonthlyStatistics(date, amount, category, true);
        System.out.println("收入已成功录入！");
    }
    private void recordExpense(Scanner scanner) {
        System.out.println("请输入支出信息：");
        System.out.print("日期 (yyyy-MM-dd): ");
        String dateStr = scanner.nextLine();
        LocalDate date = LocalDate.parse(dateStr);
        double amount;
        while (true) {
            System.out.print("金额: ");
            amount = scanner.nextDouble();
            scanner.nextLine();
            if (amount > 0) {
                break;
            } else {
                System.out.println("金额必须为正数，请重新输入。");
            }
        }
        System.out.print("类别 (如餐饮、交通、购物等): ");
        String category = scanner.nextLine();
        System.out.print("备注: ");
        String note = scanner.nextLine();
        if (amount > getRemainingBudget(date.getMonth())) {
            System.out.println("支出超出预算！");
            return;
        }
        Expense expense = new Expense(date, amount, category, note);
        expenses.add(expense);
        updateMonthlyStatistics(date, amount, category, false);
        System.out.println("支出已成功记录！");
    }
    private void displayBills() {
        System.out.println("收入记录:");
        for (Income income : incomes) {
            System.out.println(income);
        }
        System.out.println("支出记录:");
        for (Expense expense : expenses) {
            System.out.println(expense);
        }
    }
    private void queryBills(Scanner scanner) {
        System.out.println("1. 按日期查询");
        System.out.println("2. 按日期范围查询");
        System.out.println("3. 按类别查询");
        System.out.print("请选择查询方式: ");
        int choice = scanner.nextInt();
        scanner.nextLine();
        switch (choice) {
            case 1:
                queryByDate(scanner);
                break;
            case 2:
                queryByDateRange(scanner);
                break;
            case 3:
                queryByCategory(scanner);
                break;
            default:
                System.out.println("无效的选项，请重新输入。");
        }
    }

    private void queryByDate(Scanner scanner) {
        System.out.print("请输入查询日期 (yyyy-MM-dd): ");
        String dateStr = scanner.nextLine();
        LocalDate date = LocalDate.parse(dateStr);

        System.out.println("收入记录:");
        for (Income income : incomes) {
            if (income.getDate().equals(date)) {
                System.out.println(income);
            }
        }

        System.out.println("\n支出记录:");
        for (Expense expense : expenses) {
            if (expense.getDate().equals(date)) {
                System.out.println(expense);
            }
        }
    }

    private void queryByDateRange(Scanner scanner) {
        System.out.print("请输入开始日期 (yyyy-MM-dd): ");
        String startDateStr = scanner.nextLine();
        LocalDate startDate = LocalDate.parse(startDateStr);

        System.out.print("请输入结束日期 (yyyy-MM-dd): ");
        String endDateStr = scanner.nextLine();
        LocalDate endDate = LocalDate.parse(endDateStr);

        System.out.println("收入记录:");
        for (Income income : incomes) {
            if (!income.getDate().isBefore(startDate) && !income.getDate().isAfter(endDate)) {
                System.out.println(income);
            }
        }

        System.out.println("\n支出记录:");
        for (Expense expense : expenses) {
            if (!expense.getDate().isBefore(startDate) && !expense.getDate().isAfter(endDate)) {
                System.out.println(expense);
            }
        }
    }

    private void queryByCategory(Scanner scanner) {
        System.out.print("请输入查询类别: ");
        String category = scanner.nextLine();

        System.out.println("收入记录:");
        for (Income income : incomes) {
            if (income.getCategory().equals(category)) {
                System.out.println(income);
            }
        }

        System.out.println("\n支出记录:");
        for (Expense expense : expenses) {
            if (expense.getCategory().equals(category)) {
                System.out.println(expense);
            }
        }
    }
    private void setMonthlyBudget(Scanner scanner) {
        System.out.print("请输入月度预算: ");
        this.monthlyBudget = scanner.nextDouble();
        scanner.nextLine();
        System.out.println("月度预算设置成功！");
    }
    private double getMonthlyTotalExpense(Month month) {
        return monthlyTotalExpense.getOrDefault(month, 0.0);
    }
    private double getMonthlyTotalIncome(Month month) {
        return monthlyTotalIncome.getOrDefault(month, 0.0);
    }
    private void updateMonthlyStatistics(LocalDate date, double amount, String category, boolean isIncome) {
        Month month = date.getMonth();
        Map<Month, Double> totalMap = isIncome ? monthlyTotalIncome : monthlyTotalExpense;
        Map<Month, Map<String, Double>> categoryMap = isIncome ? monthlyIncomeByCategory : monthlyExpenseByCategory;
        totalMap.put(month, totalMap.getOrDefault(month, 0.0) + amount);
        categoryMap.get(month).put(category, categoryMap.get(month).getOrDefault(category, 0.0) + amount);
    }
    private double getRemainingBudget(Month month) {
        return monthlyBudget - getMonthlyTotalExpense(month);
    }
    private void showMonthlyStatistics() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要查询的月份 (如1代表一月, 2代表二月, ..., 12代表十二月): ");
        int monthNum = scanner.nextInt();
        Month month = Month.of(monthNum);
        if (!monthlyTotalIncome.containsKey(month) || !monthlyTotalExpense.containsKey(month))
        {
            System.out.println("无该月份的统计数据。");
            return;
        }
        System.out.println("月度总收入: " + getMonthlyTotalIncome(month));
        System.out.println("月度总支出: " + getMonthlyTotalExpense(month));
        System.out.println("剩余预算: " + getRemainingBudget(month));
        System.out.println("收入分类统计:");
        for (Map.Entry<String, Double> entry : monthlyIncomeByCategory.get(month).entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        System.out.println("支出分类统计:");
        for (Map.Entry<String, Double> entry : monthlyExpenseByCategory.get(month).entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}11
